home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 4 / FM Towns Free Software Collection 4 - Disc 1.iso / t_os / cdur / cdur.c < prev    next >
Text File  |  1991-10-18  |  12KB  |  452 lines

  1. /*                                                                    */
  2. /*            Cdur.C            ( Cdur.EXE LSI-C86 用ソース)            */
  3. /*                                                                    */
  4. /*                v1.00    90/11/24    By T.Takasaka                    */
  5. /*                v1.01    90/12/12    bugfix                            */
  6. /*                                    一部アセンブラ化(cdstop)        */
  7. /*                                    パラメータ数値の範囲検査をする    */
  8. /*                v1.02    90/12/13    STAT をつける                    */
  9. /*                v1.03    90/12/30    vol をつける                     */
  10. /*                v1.04    91/01/03    パラメータ無の時cd演奏中        */
  11. /*                                    なら、 新規に演奏しない            */
  12. /*                v1.05    91/07/07    パラメータ無の時でCD交換時には    */
  13. /*                                    演奏開始しないのを直した        */
  14. /*                                                                    */
  15. /*                                                                    */
  16. /*                                TAKACHAN ( IMA00356   ひかりNET )    */
  17. /*                                おくと     ( PEE01566 NIFTY-Serve )    */
  18. /*                                                                    */
  19. /*                        PS. C-Dur は ドイツ語で ハ長調の意味です    */
  20.  
  21. #define Cdur_version "v1.05"
  22. #define Cdur_date    "91/07/07"
  23.  
  24. #include <string.h>
  25. #include <stdlib.h>
  26. #include <stdio.h>
  27. #include <dos.h>
  28. #include <machine.h>
  29.  
  30. #define chkcode(track) ((cd_info.cd_time[(track)-1].cd_min) & 0x80) 
  31. #define    cd_all_flame \
  32.           (cd_info.all_min*4500+cd_info.all_sec*75+cd_info.all_flame)
  33.  
  34. #define    VOL_MAX 63
  35. #define VOL1_DAT 0x04e0
  36. #define VOL1_COM 0x04e1
  37. #define VOL2_DAT 0x04e2
  38. #define VOL2_COM 0x04e3
  39.  
  40.  
  41. typedef    struct{
  42.                     unsigned char cd_min,cd_sec,cd_flame;
  43.                 }    CD_TIME;
  44.  
  45. typedef    struct{
  46.                     CD_TIME start_t,end_t;
  47.                 }    ENSOU_T;
  48.  
  49. typedef    struct{
  50.                     unsigned char dummy1,cd_flame,dummy2;
  51.                     CD_TIME track_t;
  52.                     unsigned char    dummy3;
  53.                     CD_TIME disk_t;
  54.                 }    ENSOU_STAT;
  55.  
  56. typedef struct{
  57.                     unsigned char cd_type,start_track,end_track;
  58.                     unsigned char all_min,all_sec,all_flame;
  59.                     CD_TIME        cd_time[98];
  60.                 }    TOC;
  61.  
  62. int setvol(int vol_no,int left,int right)
  63. /* ボリュームセット 
  64.         vol_no = 0 : line in
  65.         vol_no = 1 : cd
  66.         vol_no = 2 : mic
  67.         vol_no = 3 : modem
  68. */
  69. {
  70.     unsigned char mix;
  71.  
  72.     mix  = ((left + right)/2) & VOL_MAX ;
  73.     left = left & VOL_MAX;
  74.     right = right & VOL_MAX;
  75.  
  76.     switch (vol_no)
  77.     {
  78.     case    0:
  79.         if ( left > 0 ){
  80.             outp( VOL1_COM , 0x04 );
  81.         } else {
  82.             outp( VOL1_COM , 0x00 );
  83.         }    
  84.         outp( VOL1_DAT , (unsigned char)left  );
  85.         if ( right > 0 ){
  86.             outp( VOL1_COM , 0x05 );
  87.         } else {
  88.             outp( VOL1_COM , 0x01 );
  89.         }    
  90.         outp( VOL1_DAT , (unsigned char)right  );
  91.             if ( left == right ){
  92.     printf ("\n\x1b[32mLINEのvolumeを %d に設定しました。\x1b[0m\n"
  93.                                                                         ,left);
  94.             }else{ 
  95. printf("\n\x1b[32mLINEのvolumeを 左:%d 右:%d に設定しました。\x1b[0m\n"                                                                ,left,right);
  96.             }    
  97.         break;
  98.     case    1:
  99.         if ( left > 0 ){
  100.             outp( VOL2_COM , 0x04 );
  101.         } else {
  102.             outp( VOL2_COM , 0x00 );
  103.         }    
  104.             outp( VOL2_DAT , (unsigned char)left  );
  105.         if ( right > 0 ){
  106.             outp( VOL2_COM , 0x05 );
  107.         } else {
  108.             outp( VOL2_COM , 0x01 );
  109.         }    
  110.             outp( VOL2_DAT , (unsigned char)right  );
  111.             if ( left == right ){
  112.         printf ("\n\x1b[32mCDのvolumeを %d に設定しました。\x1b[0m\n"
  113.                                                                         ,left);
  114.             }else{ 
  115. printf ("\n\x1b[32mCDのvolumeを 左:%d 右:%d に設定しました。\x1b[0m\n"
  116.                                                                 ,left,right);
  117.             }    
  118.         break;
  119.     case    2:
  120.         if ( mix > 0 ){
  121.             outp( VOL2_COM , 0x02 );
  122.             outp( VOL2_DAT , mix  );
  123.         } else {
  124.             outp( VOL2_COM , 0x00 );
  125.         }    
  126.         printf ("\n\x1b[32mMICのvolumeを %d に設定しました。\x1b[0m\n"
  127.                                     ,mix );
  128.         break;
  129.     case    3:
  130.         if ( mix > 0 ){
  131.             outp( VOL2_COM , 0x03 );
  132.             outp( VOL2_DAT , mix  );
  133.         } else {
  134.             outp( VOL2_COM , 0x00 );
  135.         }    
  136.     printf ("\n\x1b[32mMODEMのvolumeを %d に設定しました。\x1b[0m\n"
  137.                                     ,mix );
  138.         break;
  139.     default:
  140.         return(-1);
  141.     }
  142. return(0);
  143. }
  144.  
  145. int get_cd_stat()
  146. {
  147.     union    REGS    reg;
  148.     struct    SREGS    sreg;
  149.     ENSOU_STAT      cd_stat;    
  150.  
  151.     reg.x.ax = 0x53c0;
  152.     reg.x.cx = 0x0000;
  153.     reg.x.di = FP_OFF(&cd_stat);
  154.     sreg.ds     = FP_SEG(&cd_stat);
  155.         
  156.     int86x(0x93,®,®,&sreg) ;
  157.  
  158.     if ( reg.h.ah == 0 ){
  159.         if ( reg.h.al != 0 ) {
  160.             printf("\n %d 曲目を演奏しています。CD先頭から %d分 %d秒\n"
  161.                 ,cd_stat.cd_flame,cd_stat.disk_t.cd_min,cd_stat.disk_t.cd_sec);
  162.         }            
  163.         else {
  164.             printf("\nCDを演奏していません。\n");
  165.         }
  166.     }
  167.     return( (reg.h.ah == 0x80) ? reg.h.ah * 256 + reg.h.cl : reg.x.ax ); 
  168. }
  169. int    read_cd_info(TOC *cd_info)
  170. /*                                            */
  171. {
  172.     union    REGS    reg;
  173.     struct SREGS    sreg;
  174.  
  175.     reg.x.ax = 0x54c0;
  176.     reg.x.cx = 0x0000;
  177.     reg.x.di = FP_OFF(cd_info);
  178.     sreg.ds     = FP_SEG(cd_info);
  179.  
  180.     int86x(0x93,®,®,&sreg) ;
  181.     
  182.     return( (reg.h.ah == 0x80) ? reg.h.ah * 256 + reg.h.cl : reg.h.ah *256 ); 
  183.  
  184. }
  185.  
  186. int    cd_stop(); /* アセンブラ化しました cd_stop.a86 */
  187. /*
  188. {
  189.     union    REGS    reg;
  190.  
  191.     reg.x.ax = 0x52c0;
  192.     reg.x.cx = 0x0000;
  193.  
  194.     int86(0x93,®,®) ;
  195.     
  196. return( (reg.h.ah == 0x80) ? reg.h.ah * 256 + reg.h.cl : reg.h.ah *256 ); 
  197.  
  198. }
  199. */
  200.  
  201. int        _asm_time(char *, int );
  202.  
  203. #define    stop_time_asm(c) _asm_time("\n\
  204. \tMOV\tCH,255\n\
  205. \tMOV\tCL,AL\n\
  206. \tMOV\tAX,21184\n\
  207. \tINT\t147\n\
  208. \tXOR\tAL,AL\n\
  209. \tCMP\tAH,128\n\
  210. \tJNE\t__aaa\n\
  211. \tMOV\tAL,CL\n\
  212. __aaa:\t", c )
  213.  
  214. /* インラインアセンブラ化したけどあまり意味がないなぁ */    
  215.  
  216. int    cd_time(int time)
  217. {
  218.     int    err_v;
  219.     
  220.     if    ( ( err_v = stop_time_asm( time ) ) == 0 ){
  221.         if    ( time != 0 )
  222.     printf ("\n\x1b[32mCDドライブの停止時間を %d 秒に設定しました。\x1b[0m\n"
  223.                                                                         ,time);
  224.         else
  225.     printf ("\n\x1b[32mCDドライブが停止しないように設定しました。\x1b[0m\n")            ;    
  226.     }
  227. return( err_v ); 
  228. }    
  229. /*
  230. {
  231.     union    REGS    reg;
  232.  
  233.     reg.x.ax = 0x52c0;
  234.     reg.x.cx = ( 0xff00 | ( time & 0x00ff) ) ;
  235.     
  236.     int86(0x93,®,®) ;
  237.  
  238.     if    ( reg.h.ah== 0 ){
  239.         if    ( time != 0 )
  240.     printf ("\n\x1b[32mCDドライブの停止時間を %d 秒に設定しました。\x1b[0m\n"
  241.                                                                         ,time);
  242.         else
  243.     printf ("\n\x1b[32mCDドライブが停止しないように設定しました。\x1b[0m\n")            ;    
  244.     }
  245. return( (reg.h.ah == 0x80) ? reg.h.ah * 256 + reg.h.cl : reg.h.ah *256 ); 
  246. }
  247. */
  248. int    cd_start(ENSOU_T *ensou_time,int kaisuu)
  249. {
  250.     union    REGS    reg;
  251.     struct SREGS    sreg;
  252.  
  253.     reg.x.ax = 0x50c0;
  254.  
  255.         if         ( kaisuu == 0 )
  256.                 reg.x.cx = 0xff01 ;
  257.         else if    ( kaisuu == 1 )
  258.                 reg.x.cx = 0x0001 ;
  259.         else {
  260.                 reg.x.cx = 0xfe01;
  261.                 reg.h.bh = kaisuu-1;
  262.         }
  263.  
  264.     reg.x.di = FP_OFF(ensou_time);
  265.     sreg.ds     = FP_SEG(ensou_time);
  266.     
  267.     int86x(0x93,®,®,&sreg);
  268.     
  269.     return( (reg.h.ah == 0x80) ? reg.h.ah*256 + reg.h.cl : reg.h.ah *256 ); 
  270. }
  271.  
  272. long int calc_flame(CD_TIME time)
  273. {
  274.     return((time.cd_min & 0x7f)*60*75+time.cd_sec*75+time.cd_flame);
  275. }
  276.  
  277. CD_TIME calc_time(long int flame)
  278. {
  279.     CD_TIME time;
  280.  
  281.     time.cd_min=flame/(60*75);
  282.     time.cd_sec=(flame-time.cd_min*60*75)/75;
  283.     time.cd_flame=flame-time.cd_min*75*60-time.cd_sec*75;
  284.  
  285.     return(time);
  286. }
  287.  
  288. int calc_ensou(int start,int end,TOC cd_info,ENSOU_T *ensou)
  289. /*
  290.     入力 演奏開始track no. 演奏終了track no.
  291.             cd_info 
  292. */
  293. {
  294.     if (start<cd_info.start_track)    start=cd_info.start_track;
  295.     if    (chkcode(start) !=0)        start++; 
  296.     if    (start>cd_info.end_track)    start=cd_info.end_track;
  297.     if    (start==cd_info.end_track && chkcode(start)!=0)
  298.                                     return(-1);
  299.  
  300.     if    (end>cd_info.end_track)        end=cd_info.end_track;
  301.     if    (chkcode(end) !=0)            end--; 
  302.     if    (end<cd_info.start_track)    end=cd_info.start_track;
  303.     if    (end==cd_info.start_track && chkcode(end)!=0)
  304.                                     return(-1);
  305.     if    (start>end)                    return(-1);    
  306.  
  307.         (*ensou).start_t=cd_info.cd_time[start-1];
  308.     if (end==cd_info.end_track)
  309.         (*ensou).end_t=calc_time(cd_all_flame -1);
  310.     else
  311.         (*ensou).end_t=calc_time(calc_flame(cd_info.cd_time[end])-1);
  312.  
  313.     return(start*256+end);
  314. }    
  315.  
  316. void    err_r( int erf )
  317. {
  318.     if ( erf == 0x0200      )
  319.                 printf ("\n\x1b[31mデバイス番号エラー\x1b[0m\n");
  320.     if ( erf == 0x1000      )
  321.                 printf ("\n\x1b[31m音楽演奏中\x1b[0m\n");
  322.     if ( erf == 0x8001 )
  323.                 printf ("\n\x1b[31mCDがはいっていません。\x1b[0m\n");
  324.     if ( erf == 0x8002  )
  325.                 printf ("\n\x1b[31mパラメータエラー\x1b[0m\n");
  326.     if ( erf == 0x8004  )
  327.                 printf ("\n\x1b[31mドライブがつながっていません。\x1b[0m\n");
  328.     if ( erf == 0x8008  )
  329.                 printf ("\n\x1b[31mコマンド異常終了\x1b[0m\n");
  330.     if ( erf == 0x8010  )
  331.                 printf ("\n\x1b[31mCDが読み取れません。\x1b[0m\n");
  332.     if ( erf == 0x8080     )
  333.                 printf ("\n\x1b[31mCDが交換されました。\x1b[0m\n");
  334.     if (erf == -1       ){
  335. puts("                                                          ");
  336. puts("  書式    Cdur        CD を 全曲リピート再生              ");
  337. puts("          Cdur STOP   CD を 停止する                      ");
  338. puts("          Cdur PLAY [ start [ end [ loop ]]]              ");
  339. puts("                      CD を start曲目から end曲目まで     ");
  340. puts("                      loop 回 再生                        ");
  341. puts("                      loop=0 で止めるまで連続再生         ");
  342. puts("          Cdur TIME   [time]                              ");
  343. puts("                      CDが停止するまでの時間を設定する    ");
  344. puts("                      timeの単位は秒、 0 で止まらない      ");
  345. puts("          Cdur STAT   CD を 演奏情報を表示する            ");
  346. puts("          Cdur VOL  [ [ { CD | LINE | MIC | MODEM }       ");
  347. puts("                        [ left_vol  [ right_vol ] ] ] ]   ");
  348. puts("                                                          ");
  349. }
  350.  
  351. }
  352.  
  353. int cd_play_main(int start,int end,int kaisuu)
  354. {
  355.     ENSOU_T ensou_time;
  356.     TOC     cd_info;
  357.     int        tim,erf,erf1;
  358.     
  359.     cd_stop();
  360.     for (tim=0,erf=1;tim<2 && erf!=0 ;tim++)
  361.         erf=read_cd_info(&cd_info);
  362.  
  363.     if ( erf!= 0 )    return(erf);
  364.     
  365.     if ((erf1=calc_ensou(start,end,cd_info,&ensou_time))==-1 )
  366.                 return(0x8002);
  367.     
  368.     if ((erf=cd_start(&ensou_time,kaisuu))!=0) return(erf);
  369.  
  370.     if ((erf1/256)==(erf1 % 256))
  371.         printf("\n\x1b[36m %d 曲目を",(erf1 / 256));
  372.     else
  373.        printf("\n\x1b[36m %d 曲目から %d 曲目まで",(erf1/256),(erf1 % 256));
  374.  
  375.     if ( kaisuu == 0)
  376.         printf("繰り返し演奏します\x1b[0m\n");
  377.     else if (kaisuu==1)  
  378.         printf("演奏します\x1b[0m\n");
  379.     else if (kaisuu>=1)  
  380.         printf(" %d 回演奏します\x1b[0m\n",kaisuu);
  381.     return(0);
  382. }
  383.  
  384.  
  385.  
  386.  
  387. main(int argc,char *argv[])
  388. {
  389.     int        start=1, end=99, kaisuu=1, time=0 ,erf=-1;
  390.     int        vol_set = 1,vol_left=VOL_MAX,vol_right=VOL_MAX;        
  391.  
  392.     printf("\n\x1b[32m");
  393.     printf("*** \x1b[36mCdur.exe \x1b[31m♪\x1b[32m    ");
  394.     printf( Cdur_version );
  395.     printf( "   " );
  396.     printf( Cdur_date );
  397.     printf("    By おくと ***\n\x1b[0m");
  398.  
  399.     if (argc==1){
  400.         erf=get_cd_stat();    
  401.         if (erf == 0x0000 ){     
  402.             erf=cd_play_main(0,99,0);
  403.         }
  404.         if (erf == 0x8080){     
  405.              erf=get_cd_stat();    
  406.             erf=cd_play_main(0,99,0);
  407.         }
  408.     }
  409.     if (argc>=2 && strcmpi(argv[1],"stop")== 0 ){
  410.             erf=cd_stop();     
  411.             if    ( erf== 0 )
  412.                 printf ("\n\x1b[1;34mCDを停止しました。\x1b[0m\n");
  413.     }
  414.     if (argc>=2 && strcmpi(argv[1],"play")== 0 ){
  415.         if    (argc>=3)    start    = atoi(argv[2]) ;
  416.         if    (argc>=4)    end        = atoi(argv[3])    ;
  417.         if    (argc>=5)    kaisuu    = atoi(argv[4]) ;
  418.         if ( 0<=start && start<=99 && 0<=end && end<=99 
  419.                         && 0<=kaisuu && kaisuu<=256 )
  420.         erf=cd_play_main(start,end,kaisuu);
  421.     }
  422.     if (argc>=2 && strcmpi(argv[1],"time")== 0 ){
  423.         if    (argc>=3)                     time    = atoi(argv[2]) ;
  424.         if    ( 0 <= time && time <= 255 ) erf    = cd_time(time) ;
  425.     }
  426.  
  427.     if ( argc==2 && strcmpi(argv[1],"stat")== 0 ){
  428.             erf=get_cd_stat() & 0xff00 ;     
  429.     }
  430.  
  431.     if ( argc>=2 && strcmpi(argv[1],"vol")== 0 ){
  432.             if ( argc== 5 ){
  433.                 vol_left = atoi(argv[3]) ; 
  434.                 vol_right = atoi(argv[4]); 
  435.             }
  436.             else if ( argc == 4 ) { 
  437.                 vol_left=vol_right=atoi(argv[3]) ;
  438.             }
  439.             
  440.             if ( argc>=3 && strcmpi(argv[2],"cd") == 0 )         vol_set=1; 
  441.             else if ( argc>=3 && strcmpi(argv[2],"line") == 0 ) vol_set=0;
  442.             else if ( argc>=3 && strcmpi(argv[2],"mic") == 0 )     vol_set=2;
  443.             else if ( argc>=3 && strcmpi(argv[2],"modem") == 0 ) vol_set=3;
  444.      
  445.             if ( 0<= vol_left && vol_left<=VOL_MAX 
  446.                                     && 0<=vol_right && vol_right<=VOL_MAX)
  447.                 erf = setvol( vol_set , vol_left , vol_right );
  448.     }
  449.  
  450.     err_r(erf);
  451. }
  452.